/**
 * 循环检测是否完成
 */

import type { Ref } from 'vue'
import { computed, ref, watch } from 'vue'

export const useCheckDone = function (
    fn: () => boolean,
    interval = 300,
    isRunFirst = true,
    times = Infinity
) {
    let isStop = false
    async function check(curTimes = 0): Promise<boolean> {
        if (curTimes === 0) {
            start()
        }
        return await new Promise((resolve) => {
            if (isStop || (curTimes === 0 && isRunFirst && fn()) || curTimes >= times || fn()) {
                resolve(true)
            } else {
                setTimeout(() => {
                    resolve(check(curTimes++))
                }, interval)
            }
        })
    }

    function stop() {
        isStop = true
    }

    function start() {
        isStop = false
    }

    return {
        stop,
        start,
        check
    }
}

/**
 * 检测是否完成
 * @param watchRef ref对象
 * @returns
 */
export function useCheckDoneByWatch(watchRef: Ref<boolean>) {
    const isStop = ref(false)
    const isOver = computed(() => watchRef.value || isStop.value)

    function stop() {
        isStop.value = true
    }

    function start() {
        isStop.value = false
    }

    async function check(): Promise<boolean> {
        start()

        if (isOver.value) {
            return true
        }

        return await new Promise((resolve) => {
            const stopWatchFlag = watch(
                isOver,
                (val) => {
                    if (val) {
                        resolve(true)
                        if (stopWatchFlag) {
                            stopWatchFlag()
                        }
                    }
                },
                {
                    immediate: true
                }
            )
        })
    }

    return {
        stop,
        start,
        check
    }
}
